package global

import (
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"strings"

	"GoApi/utils/config"

	"github.com/astaxie/beego/logs"
	"gorm.io/gorm"
)

var (
	//DB 数据库操作
	DB *gorm.DB
	//Conf 配置相关
	Conf *config.Config
	//Log 日志
	Log *logs.BeeLogger
	//RD redis
	RD *config.RedisConnPool
	NetWorkList   []*config.NetWorkInfo
	TokenList     []*config.TokenInfo
)

type NetWorkInfo struct {
	Name              string
	ChainID           int
	RpcUrl            string
	WsNodeUrl         string
	StableCoin        string
	StableCoinDecimal int
	MainCoinName      string
	MarketContract    string
}

//ConfPath 配置文件路径
type ConfPath struct {
	ConfigPath string
}

//InitGlobal 初始化各项配置
func InitGlobal(confPath *ConfPath) (err error) {
	// init configfile
	Conf, err = config.LoadGlobalConfig(confPath.ConfigPath)
	if err != nil {
		err = errors.New(fmt.Sprintf("init configfile fail，error：%s", err.Error()))
		return
	}
	// init db
	DB, err = config.NewGorm(Conf)
	if err != nil {
		err = errors.New(fmt.Sprintf("init db fail,error：%s", err.Error()))
		return
	}

	Log = config.InitLog(Conf.Log)
	//init redis
	RD, err = config.InitRedis(Conf.Redis, Conf.Project.Name)
	if err != nil {
		err = fmt.Errorf(fmt.Sprintf("init redis fail，error：%s", err.Error()))
		return
	}
	// init NetWorkList
	netWorkInfoJson, err := ioutil.ReadFile(Conf.RunParams.NetWorkInfoPath)
	if err != nil {
		err = fmt.Errorf(fmt.Sprintf("init NetWorkList ReadFile error：%s", err.Error()))
		return
	}
	if err = json.Unmarshal(netWorkInfoJson, &NetWorkList); err != nil {
		err = fmt.Errorf(fmt.Sprintf("init NetWorkList json.Unmarshal error：%s", err.Error()))
		return
	}
	// init TokenList
	tokenListJson, err := ioutil.ReadFile(Conf.RunParams.TokenInfoPath)
	if err != nil {
		err = fmt.Errorf(fmt.Sprintf("init TokenList ReadFile error：%s", err.Error()))
		return
	}
	if err = json.Unmarshal(tokenListJson, &TokenList); err != nil {
		err = fmt.Errorf(fmt.Sprintf("init TokenList json.Unmarshal error：%s", err.Error()))
		return
	}
	return
}

func InitNetWorkInfo() (ok bool) {
	netWorkInfoJson, err := ioutil.ReadFile(Conf.RunParams.NetWorkInfoPath)
	if err != nil {
		Log.Error("init NetWorkList ReadFile error：%s", err.Error())
		return
	}
	if err := json.Unmarshal(netWorkInfoJson, &NetWorkList); err != nil {
		Log.Error("init NetWorkList json.Unmarshal error：%s", err.Error())
		return
	}
	return true
}

func GetNewWorkInfo(chainID int) (netWorkInfo *config.NetWorkInfo) {
	for index, newtWork := range NetWorkList {
		if newtWork.ChainID == chainID {
			netWorkInfo = NetWorkList[index]
			break
		}
	}
	return
}

func GetTokenInfo(chainID int, tokenAdr string) (tokenInfo *config.TokenInfo) {
	for index, tokenInfoT := range TokenList {
		if tokenInfoT.ChainID == chainID && strings.EqualFold(tokenInfoT.Address, tokenAdr) {
			tokenInfo = TokenList[index]
			break
		}
	}
	return
}

func GetSwapTokenPath(chainID int, tokenAdr string) (swapTokenPath *config.TokenInfo) {
	for index, tokenInfoT := range TokenList {
		if tokenInfoT.ChainID == chainID && strings.EqualFold(tokenInfoT.Address, tokenAdr) {
			swapTokenPath = TokenList[index]
			break
		}
	}
	return
}

func GetTokenInfoBySymbol(chainID int, symbol string) (tokenInfo *config.TokenInfo) {
	for index, tokenInfoT := range TokenList {
		if tokenInfoT.ChainID == chainID && strings.EqualFold(tokenInfoT.Symbol, symbol) {
			tokenInfo = TokenList[index]
			break
		}
	}
	return
}
